home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / AppsToGo / Kibitz / Menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  14.1 KB  |  524 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        menu.c
  5. ** Written by:  Eric Soldan
  6. **
  7. ** Copyright © 1990-1992 Apple Computer, Inc.
  8. ** All rights reserved. */
  9.  
  10.  
  11.  
  12. /*****************************************************************************/
  13.  
  14.  
  15.  
  16. #include "Kibitz.h"                /* Get the Kibitz includes/typedefs, etc.    */
  17. #include "KibitzCommon.h"        /* Get the stuff in common with rez.        */
  18. #include "Kibitz.protos"        /* Get the prototypes for Kibitz.            */
  19.  
  20. #ifndef __DESK__
  21. #include <Desk.h>
  22. #endif
  23.  
  24. #ifndef __ERRORS__
  25. #include <Errors.h>
  26. #endif
  27.  
  28. #ifndef __MENUS__
  29. #include <Menus.h>
  30. #endif
  31.  
  32. #ifndef __TEXTEDITCONTROL__
  33. #include <TextEditControl.h>
  34. #endif
  35.  
  36. #ifndef __TOOLUTILS__
  37. #include <ToolUtils.h>
  38. #endif
  39.  
  40. #ifndef __UTILITIES__
  41. #include <Utilities.h>
  42. #endif
  43.  
  44.  
  45.  
  46. /*****************************************************************************/
  47.  
  48.  
  49.  
  50. extern Boolean    gQuitApplication;
  51. extern Boolean    gHasAppleEvents;
  52. extern Boolean    gHasPPCToolbox;
  53. extern Boolean    gSendToSelf;
  54. extern short    gReplyMode;
  55. extern Boolean    gDescriptive;
  56.  
  57. short            gMenuMods;
  58.  
  59.  
  60.  
  61. /*****************************************************************************/
  62. /*****************************************************************************/
  63.  
  64. #ifdef applec
  65. #pragma segment Menu
  66. #endif
  67.  
  68. /*****************************************************************************/
  69. /*****************************************************************************/
  70.  
  71.  
  72.  
  73. /* Enable and disable menus based on the current state.  The user can only
  74. ** select enabled menu items.  We set up all the menu items before calling
  75. ** MenuSelect or MenuKey, since these are the only times that a menu item can
  76. ** be selected.  Note that MenuSelect is also the only time the user will see
  77. ** menu items.  This approach to deciding what enable/ disable state a menu
  78. ** item has the advantage of concentrating all the decision-making in one
  79. ** routine, as opposed to being spread throughout the application.  Other
  80. ** application designs may take a different approach that is just as valid. */
  81.  
  82. void    AdjustMenus(void)
  83. {
  84.     WindowPtr        window;
  85.     MenuHandle        menu;
  86.     short            numWindows, activeItem;
  87.     Boolean            maxWindows, menuEnabled, redrawMenuBar, winIsDirty, fileIsOpen;
  88.     TEHandle        teHndl;
  89.     Rect            rct;
  90.     FileRecHndl        frHndl;
  91.     static Boolean    editMenuEnabled   = true;
  92.     static Boolean    gameMenuEnabled   = true;
  93.  
  94.     redrawMenuBar = false;
  95.     window = FrontWindow();
  96.  
  97.     if (IsAppWindow(window)) frHndl = (FileRecHndl)GetWRefCon(window);
  98.  
  99.     menu = GetMenuHandle(mFile);
  100.  
  101.     EnableItem(menu, iNew);                /* Set these for the no-windows state. */
  102.     EnableItem(menu, iOpen);
  103.     EnableItem(menu, iMessage);
  104.     if (MaxBlock() < 0x10000L) {
  105.         if (CompactMem(0x10000L) < 0x10000L) {
  106.             DisableItem(menu, iNew);    /* Running low on RAM. */
  107.             DisableItem(menu, iOpen);
  108.         }
  109.     }
  110.  
  111.     DisableItem(menu, iClose);
  112.     DisableItem(menu, iSave);
  113.     DisableItem(menu, iSaveAs);
  114.     DisableItem(menu, iSaveBoardImage);
  115.     DisableItem(menu, iDuplicate);
  116.     DisableItem(menu, iRevert);
  117.     DisableItem(menu, iPageSetup);
  118.     DisableItem(menu, iPrint);
  119.         /* Quit is always hilited. */
  120.  
  121.  
  122.  
  123.     if (IsDAWindow(window)) {
  124.         DisableItem(menu, iNew);        /* DAs don't get to do a new. */
  125.         DisableItem(menu, iOpen);        /* DAs don't get to do an open. */
  126.         DisableItem(menu, iMessage);    /* DAs don't get to do a new. */
  127.         EnableItem(menu, iClose);        /* Let DAs do a close from the menu. */
  128.     }
  129.  
  130.     if (IsAppWindow(window)) {
  131.         numWindows = GetWindowCount(false, false, false);
  132.         maxWindows = (numWindows < kMaxNumWindows);
  133.         EnableOrDisableItem(menu, iNew, maxWindows);
  134.         EnableOrDisableItem(menu, iOpen, maxWindows);
  135.         EnableOrDisableItem(menu, iMessage, maxWindows);
  136.             /* Allow a new and open only if max number of files not reached. */
  137.  
  138.         winIsDirty = AppWindowDirty(window);
  139.         fileIsOpen = ((*frHndl)->fileState.fss.vRefNum != kInvalVRefNum);
  140.  
  141.         EnableItem(menu, iClose);
  142.         EnableOrDisableItem(menu, iSave, winIsDirty);
  143.         EnableItem(menu, iSaveAs);
  144.         if ((*frHndl)->doc.myColor != kMessageDoc) EnableItem(menu, iSaveBoardImage);
  145.         EnableItem(menu, iDuplicate);
  146.         EnableOrDisableItem(menu, iRevert, ((winIsDirty) && (fileIsOpen)));
  147.  
  148.         EnableItem(menu, iPageSetup);
  149.         EnableItem(menu, iPrint);
  150.     }
  151.  
  152.  
  153.  
  154.     menu = GetMenuHandle(mEdit);
  155.     DisableItem(menu, iSelectAll);
  156.     if (IsDAWindow(window)) {        /* A desk accessory may need edit menu. */
  157.         menuEnabled = true;
  158.         EnableItem(menu, iUndo);
  159.         EnableItem(menu, iCut);
  160.         EnableItem(menu, iCopy);
  161.         EnableItem(menu, iPaste);
  162.         EnableItem(menu, iClear);
  163.     } else {
  164.         menuEnabled = false;
  165.         if (window) {
  166.             CTEEditMenu(&menuEnabled, mEdit, iUndo, iCut);
  167.             if (CTETargetInfo(&teHndl, &rct) == window) {
  168.                 if ((*teHndl)->teLength) {
  169.                     EnableItem(menu, iSelectAll);
  170.                     menuEnabled = true;
  171.                 }
  172.             }
  173.         }
  174.     }
  175.     if (editMenuEnabled != menuEnabled) {
  176.         redrawMenuBar = true;
  177.         editMenuEnabled = menuEnabled;
  178.         if (editMenuEnabled) EnableItem(menu, 0);
  179.         else                 DisableItem(menu, 0);
  180.     }
  181.  
  182.  
  183.  
  184.     menu = GetMenuHandle(mGame);                /* Start by disabling everything. */
  185.     menuEnabled = false;
  186.     DisableItem(menu, iConfigureGame);
  187.     DisableItem(menu, iInvertBoard);
  188.     DisableItem(menu, iArrangeBoard);
  189.     DisableItem(menu, iPlayOnePlayer);
  190.     DisableItem(menu, iPlayTwoPlayer);
  191.     DisableItem(menu, iFindTwoPlayer);
  192.     DisableItem(menu, iGoToMove);
  193.     DisableItem(menu, iNotationOut);
  194.     DisableItem(menu, iNotationIn);
  195.  
  196.     EnableItem(menu, iAlgNotation);
  197.     EnableItem(menu, iDescNotation);
  198.  
  199.     CheckItem(menu, iArrangeBoard, false);
  200.     CheckItem(menu, iPlayOnePlayer, false);
  201.     CheckItem(menu, iPlayTwoPlayer, false);
  202.     CheckItem(menu, iFindTwoPlayer, false);
  203.     CheckItem(menu, iAlgNotation, (!gDescriptive));
  204.     CheckItem(menu, iDescNotation, gDescriptive);
  205.  
  206.     if (IsAppWindow(window)) {
  207.  
  208.         if (!(*frHndl)->fileState.readOnly) {
  209.  
  210.             if ((*frHndl)->doc.myColor != kMessageDoc) {
  211.  
  212.                 menuEnabled = true;
  213.  
  214.                 if (!(*frHndl)->doc.arrangeBoard) {
  215.                     EnableItem(menu, iConfigureGame);
  216.                     EnableItem(menu, iArrangeBoard);
  217.                 }
  218.                 EnableItem(menu, iInvertBoard);
  219.                 EnableItem(menu, iPlayOnePlayer);
  220.                 if (gHasAppleEvents) {                /* Now the 7.0 goodie... */
  221.                     EnableItem(menu, iPlayTwoPlayer);
  222.                     EnableItem(menu, iFindTwoPlayer);
  223.                 }
  224.  
  225.                 if ((*frHndl)->doc.numGameMoves)
  226.                     EnableItem(menu, iGoToMove);
  227.  
  228.                 if ((*frHndl)->doc.gameIndex < (*frHndl)->doc.numGameMoves) {
  229.                     EnableItem(menu, iNotationOut);
  230.                 }
  231.  
  232.                 teHndl = (*frHndl)->doc.message[kMessageOut];
  233.                 if ((*teHndl)->selStart != (*teHndl)->selEnd)
  234.                     EnableItem(menu, iNotationIn);
  235.  
  236.                 activeItem = iPlayOnePlayer + (*frHndl)->doc.twoPlayer;
  237.                 if ((*frHndl)->doc.arrangeBoard) activeItem = iArrangeBoard;
  238.                 DisableItem(menu, activeItem);
  239.                 if (activeItem == iPlayTwoPlayer) DisableItem(menu, iFindTwoPlayer);
  240.                 CheckItem(menu, activeItem, true);
  241.             }
  242.         }
  243.     }
  244.     if (gameMenuEnabled != menuEnabled) {
  245.         redrawMenuBar = true;
  246.         gameMenuEnabled = menuEnabled;
  247.         if (gameMenuEnabled)
  248.              EnableItem(menu, 0);
  249.         else DisableItem(menu, 0);
  250.     }
  251.  
  252.  
  253.  
  254.     if (redrawMenuBar) DrawMenuBar();
  255. }
  256.  
  257.  
  258.  
  259. /*****************************************************************************/
  260.  
  261.  
  262.  
  263. /* This function either enables or disables a menu item. */
  264.  
  265. void    EnableOrDisableItem(MenuHandle menu, short item, Boolean enable)
  266. {
  267.     if (enable) EnableItem(menu, item);
  268.     else        DisableItem(menu, item);
  269. }
  270.  
  271.  
  272.  
  273. /*****************************************************************************/
  274.  
  275.  
  276.  
  277. /* This is called when an item is chosen from the menu bar (after calling
  278. ** MenuSelect or MenuKey).  It performs the right operation for each command.
  279. ** It is good to have both the result of MenuSelect and MenuKey go to one
  280. ** routine like this to keep everything organized. */
  281.  
  282. void    DoMenuCommand(long menuResult, EventRecord *event)
  283. {
  284.     short        menuID;            /* The resource ID of the selected menu. */
  285.     short        menuItem;        /* The item number of the selected menu. */
  286.     Str255        daName;
  287.     short        daRefNum, arrangeBoard;
  288.     FileRecHndl    frHndl, newFrHndl;
  289.     OSErr        err;
  290.     WindowPtr    window, oldPort;
  291.     short        itemHit;
  292.     DialogPtr    dlg;
  293.     StringPtr    nbpType;
  294.     TEHandle    teHndl;
  295.     Rect        rct;
  296.  
  297.     gMenuMods = event->modifiers;
  298.  
  299.     window = FrontWindow();
  300.     if (window)
  301.         frHndl = (FileRecHndl)GetWRefCon(window);
  302.             /* frHndl is valid only if it is one of our windows. */
  303.  
  304.     menuID = HiWord(menuResult);    /* Use macros for efficiency to get */
  305.     menuItem = LoWord(menuResult);    /* menu item number and menu number. */
  306.  
  307.     switch (menuID) {
  308.  
  309.         case mApple:
  310.             switch (menuItem) {
  311.                 case iAbout:    /* Bring up alert for About. */
  312.                     Alert(rAboutAlert, gAlertFilterUPP);
  313.                     break;
  314.                 default:        /* All non-About items in this menu are DAs. */
  315.                     GetMenuItemText(GetMenuHandle(mApple), menuItem, daName);
  316.                     daRefNum = OpenDeskAcc(daName);
  317.                     break;
  318.             }
  319.             break;
  320.  
  321.         case mFile:
  322.             switch (menuItem) {
  323.                 case iNew:
  324.                     err = AppNewDocument(&frHndl, ksOrigName);
  325.                     if (!err) {
  326.                         (*frHndl)->doc.compMovesBlack = true;
  327.                         err = AppNewWindow(frHndl, nil, (WindowPtr)-1);
  328.                         if (err)
  329.                             AppDisposeDocument(frHndl);
  330.                     }
  331.                     if (err) Alert(rErrorAlert, gAlertFilterUPP);
  332.                     break;
  333.                 case iOpen:
  334.                     err = AppOpenDocument(&frHndl, nil, fsRdWrPerm);
  335.                     if (!err) {
  336.                         err = AppNewWindow(frHndl, nil, (WindowPtr)-1);
  337.                         if (err)
  338.                             AppDisposeDocument(frHndl);
  339.                         else
  340.                             AppAutoLaunch(frHndl);
  341.                     }
  342.                     if ((err) && (err != userCanceledErr))
  343.                         Alert(rErrorAlert, gAlertFilterUPP);
  344.                     break;
  345.                 case iMessage:
  346.                     err = AppNewDocument(&frHndl, ksMssgName);
  347.                     if (!err) {
  348.                         err = AppNewWindow(frHndl, nil, (WindowPtr)-1);
  349.                         if (err)
  350.                             AppDisposeDocument(frHndl);
  351.                     }
  352.                     if (err) Alert(rErrorAlert, gAlertFilterUPP);
  353.                     break;
  354.                 case iClose:
  355.                     CloseOneWindow(window, iClose);
  356.                     break;
  357.                 case iSave:
  358.                     err = AppSaveDocument(frHndl, window, iSave);
  359.                     if ((err) && (err != userCanceledErr))
  360.                         Alert(rErrorAlert, gAlertFilterUPP);
  361.                     break;
  362.                 case iSaveAs:
  363.                     err = AppSaveDocument(frHndl, window, iSaveAs);
  364.                     if ((err) && (err != userCanceledErr))
  365.                         Alert(rErrorAlert, gAlertFilterUPP);
  366.                     break;
  367.                 case iSaveBoardImage:
  368.                     err = SaveBoardImage(frHndl);
  369.                     if ((err) && (err != userCanceledErr))
  370.                         Alert(rErrorAlert, gAlertFilterUPP);
  371.                     break;
  372.                 case iDuplicate:
  373.                     err = AppDuplicateDocument(frHndl, &newFrHndl);
  374.                     if (!err) {
  375.                         err = AppNewWindow(newFrHndl, nil, (WindowPtr)-1);
  376.                         if (err)
  377.                             AppDisposeDocument(newFrHndl);
  378.                     }
  379.                     if (err) Alert(rErrorAlert, gAlertFilterUPP);
  380.                     break;
  381.                 case iRevert:
  382.                     DoSetCursor(&qd.arrow);
  383.                     dlg = GetCenteredDialog(rRevertWarning, nil, FrontWindow(), (WindowPtr)-1L);
  384.                     if (dlg) {
  385.                         OutlineDialogItem(dlg, 1);
  386.                         ModalDialog(gKeyEquivFilterUPP, &itemHit);
  387.                         DisposeDialog(dlg);
  388.                         if (itemHit == 3) break;
  389.                     }
  390.                     if ((*frHndl)->doc.twoPlayer) SetOpponentType(frHndl, kOnePlayer);
  391.                     if (!(AppReadDocument(frHndl, gameFileType))) {
  392.                         arrangeBoard = (*frHndl)->doc.arrangeBoard;
  393.                         if (arrangeBoard)
  394.                             if (CTETargetInfo(&teHndl, &rct) == window)
  395.                                 CTEActivate(false, teHndl);
  396.                         oldPort = SetFilePort(frHndl);
  397.                         rct = window->portRect;
  398.                         EraseRect(&rct);
  399.                         ImageDocument(frHndl, false);
  400.                         if (!arrangeBoard) AdjustGameSlider(frHndl);
  401.                         UpdateGameStatus(frHndl);
  402.                         DrawTime(frHndl);
  403.                         SetPort(oldPort);
  404.                         if (!arrangeBoard) CTEWindActivate(window, true);
  405.                     }
  406.                     break;
  407.                 case iPageSetup:
  408.                     DoSetCursor(&qd.arrow);
  409.                     PresentStyleDialog(frHndl);
  410.                     break;
  411.                 case iPrint:
  412.                     DoSetCursor(&qd.arrow);
  413.                     err = noErr;
  414.                     if (!(*frHndl)->doc.printRecValid)
  415.                         err = PresentStyleDialog(frHndl);
  416.                     if (!err) {
  417.                         err = AppPrintDocument(frHndl, true, true);
  418.                         AppPrintDocument(nil, false, false);
  419.                     }
  420.                     if ((err) && (err != userCanceledErr))
  421.                         Alert(rErrorAlert, gAlertFilterUPP);
  422.                     break;
  423.                 case iQuit:
  424.                     gQuitApplication = CloseAllWindows();
  425.                     break;
  426.             }
  427.             break;
  428.  
  429.         case mEdit:            /* Call SystemEdit for DA editing & MultiFinder. */
  430.             if (IsAppWindow(window)) {
  431.                 switch (menuItem) {
  432.                     case iUndo:
  433.                         CTEUndo();
  434.                         break;
  435.                     case iCut:
  436.                     case iCopy:
  437.                     case iPaste:
  438.                     case iClear:
  439.                         CTEClipboard(menuItem - iCut + 2);
  440.                         if (menuItem != iCopy) (*frHndl)->fileState.docDirty = true;
  441.                         break;
  442.                     case iSelectAll:
  443.                         if (CTETargetInfo(&teHndl, &rct) == window) CTESetSelect(0, 32000, teHndl);
  444.                         break;
  445.                 }
  446.             }
  447.             else SystemEdit(menuItem - 1);
  448.             break;
  449.  
  450.         case mGame:
  451.             switch (menuItem) {
  452.                 case iConfigureGame:
  453.                     DoSetCursor(&qd.arrow);
  454.                     DoConfigureGame(frHndl);
  455.                     break;
  456.                 case iInvertBoard:
  457.                     (*frHndl)->doc.invertBoard ^= 1;
  458.                     if (!(*frHndl)->doc.twoPlayer) {
  459.                         if ((*frHndl)->doc.compMovesWhite + (*frHndl)->doc.compMovesBlack == 1) {
  460.                             if ((*frHndl)->doc.compMovesWhite == (*frHndl)->doc.myColor) {
  461.                                 (*frHndl)->doc.compMovesWhite ^= true;
  462.                                 (*frHndl)->doc.compMovesBlack ^= true;
  463.                                 (*frHndl)->doc.myColor        ^= true;
  464.                             }
  465.                         }
  466.                     }
  467.                     SetPort(window);
  468.                     ImageDocument(frHndl, true);
  469.                     DrawTime(frHndl);
  470.                     break;
  471.                 case iArrangeBoard:
  472.                 case iPlayOnePlayer:
  473.                 case iPlayTwoPlayer:
  474.                 case iFindTwoPlayer:
  475.                     DoSetCursor(&qd.arrow);
  476.                     if ((menuItem == iArrangeBoard) && ((*frHndl)->doc.numGameMoves)) {
  477.                         dlg = GetCenteredDialog(rArrangeWarning, nil, FrontWindow(), (WindowPtr)-1L);
  478.                         if (dlg) {
  479.                             OutlineDialogItem(dlg, 1);
  480.                             ModalDialog(gKeyEquivFilterUPP, &itemHit);
  481.                             DisposeDialog(dlg);
  482.                             if (itemHit == 3) break;
  483.                         }
  484.                     }
  485.                     nbpType = nil;
  486.                     if (menuItem == iFindTwoPlayer) {
  487.                         menuItem = iPlayTwoPlayer;
  488.                         nbpType = "\pKibitz";
  489.                     }
  490.                     if (menuItem == iPlayTwoPlayer) {
  491.                         if (!(*frHndl)->doc.twoPlayer) SendGame(frHndl, kIsMove, nbpType);
  492.                     }
  493.                     else SetOpponentType(frHndl, menuItem - iPlayOnePlayer + kOnePlayer);
  494.                     break;
  495.                 case iGoToMove:
  496.                     DoGoToMove(frHndl);
  497.                     break;
  498.                 case iNotationOut:
  499.                     DoSetCursor(*GetCursor(watchCursor));
  500.                     MovesToOutBox(frHndl, event);
  501.                     break;
  502.                 case iNotationIn:
  503.                     DoSetCursor(*GetCursor(watchCursor));
  504.                     teHndl = (*frHndl)->doc.message[kMessageOut];
  505.                     MovesFromText(frHndl, (*teHndl)->hText, (*teHndl)->teLength,
  506.                                   (*teHndl)->selStart, (*teHndl)->selEnd, false);
  507.                     break;
  508.                 case iAlgNotation:
  509.                     gDescriptive = false;
  510.                     break;
  511.                 case iDescNotation:
  512.                     gDescriptive = true;
  513.                     break;
  514.             }
  515.             break;
  516.  
  517.     }
  518.  
  519.     HiliteMenu(0);        /* Unhighlight what MenuSelect (or MenuKey) hilited. */
  520. }
  521.  
  522.  
  523.  
  524.